﻿#include "CameraBasler.h"
#include <Windows.h>
#include "logger.h"
#include <QDebug>
#include <QTime>
#include <QThread>

MyImageEventHandler::MyImageEventHandler():QObject()
{

}
void MyImageEventHandler::OnImageGrabbed( Pylon::CBaslerUniversalInstantCamera& camera, const Pylon::CBaslerUniversalGrabResultPtr& grabResult )
{
    if (grabResult.IsValid() && grabResult->GrabSucceeded())
    {
        ImageInfo imgInfo={0};

        if ( grabResult->GetPixelType() == Pylon::PixelType_Mono8)
        {

        } else {
            Pylon::CPylonImage tarImage;
            // Create the converter and set parameters.
            Pylon::CImageFormatConverter converter;
            converter.OutputPixelFormat = Pylon::PixelType_BGR8packed;
            converter.Convert(tarImage, grabResult);
            imgInfo.pData = (uchar*)grabResult->GetBuffer();
        }
        imgInfo.nWidth = grabResult->GetWidth();
        imgInfo.nHeight = grabResult->GetHeight();
        imgInfo.pData = (uchar*)grabResult->GetBuffer();
        imgInfo.nDataLen = Pylon::ComputeBufferSize(grabResult->GetPixelType(), grabResult->GetWidth(), grabResult->GetHeight(), grabResult->GetPaddingX());
        imgInfo.enPixelType = grabResult->GetPixelType();
        emit imageGrabbed(imgInfo);
    }

}
MyConfigurationEventHandler::MyConfigurationEventHandler():QObject()
{

}
void MyConfigurationEventHandler::OnCameraDeviceRemoved(CInstantCamera &camera)
{
    printf(tr("OnCameraDeviceRemoved called").toLocal8Bit().data());
    LOG(WARNING)<< tr("Camera Removed").toLocal8Bit().data();
    emit cameraRemoved();
}

MyEventHandler::MyEventHandler():QObject()
{

}
void MyEventHandler::OnCameraEvent(CBaslerUniversalInstantCamera& camera, intptr_t userProvidedId, GenApi::INode* /* pNode */)
{
    switch (userProvidedId)
    {
        case 10001: // Exposure End event
            emit sigCameraTrigger();
            break;
    }
}



CameraBasler::CameraBasler(const std::string name):Camera(name)
{
    PylonInitialize();
    m_imageHandler = new MyImageEventHandler();
    m_configHandler = new MyConfigurationEventHandler();
    m_eventHandler = new MyEventHandler();
    connect(m_imageHandler,&MyImageEventHandler::imageGrabbed,this, &CameraBasler::preProcessImage);
    connect(m_configHandler,&MyConfigurationEventHandler::cameraRemoved,this, [this](){
        setStatus(Unavailable);
        reStart();
    });
    connect(m_eventHandler,&MyEventHandler::sigCameraTrigger, this, [&](){
        emit sigTriggerRisingEdge(getName());
    });


}

CameraBasler::~CameraBasler()
{


}


void CameraBasler::initialize()
{
    QMutexLocker mutexLocker(&m_lock);
    setStatus(Unavailable);
    Pylon::DeviceInfoList_t devices;
    try{
        //枚举设备
        Pylon::CTlFactory& TlFactory = Pylon::CTlFactory::GetInstance();
        TlFactory.EnumerateDevices( devices );
    } catch (const Pylon::GenericException& e){
        PYLON_UNUSED( e );
        devices.clear();
        printf(e.GetDescription());
        return;
    }
    //如果相机的个数为0
    if (int(devices.size()) == 0){
        printf( tr("No camera found.\n").toLocal8Bit().data() );
        return;
    }
    //获得相机的index
    int nIndex = -1;
    for (unsigned int i = 0; i < devices.size(); i++){
        printf(tr("[device %1]:\n").arg(i).toLocal8Bit().data());
        const Pylon::CDeviceInfo* pDeviceInfo = &devices[i];
        if (NULL == pDeviceInfo){
            break;
        }
        //判断相机是否是GIGE类型的相机
        if(pDeviceInfo->GetDeviceClass() == Pylon::BaslerGigEDeviceClass){
            std::string cameraName = std::string(pDeviceInfo->GetUserDefinedName().c_str());
            if(cameraName==m_name){
                nIndex=i;
                break;
            }
        }
    }

    if (nIndex == -1){
        printf(tr("%1 unavailable:\n").arg(QString::fromStdString(m_name)).toLocal8Bit().data());
        return ;
    }
    Pylon::IPylonDevice* pDevice = Pylon::CTlFactory::GetInstance().CreateDevice( devices[nIndex] );

    m_camera.Attach(pDevice,Pylon::Cleanup_Delete);

    //注册事件回调
    if(!m_isNotRegisterImageCallBack){
        m_camera.RegisterImageEventHandler(m_imageHandler, Pylon::RegistrationMode_ReplaceAll, Pylon::Cleanup_Delete );
    }

    setStatus(Closed);
    printf(tr("%1 init success:\n").arg(QString::fromStdString(m_name)).toLocal8Bit().data());
}

void CameraBasler::openCamera()
{
    if(m_status != Closed)
        return;
    try {
        m_camera.Open();
        if (!m_camera.IsOpen())
        {
            printf(tr("Open Device fail!\n").toLocal8Bit().data());
            return;
        }
        
        //设置心跳时间
        m_camera.GetTLParams().HeartbeatTimeout.SetValue(2000);

        //设置相机采集方式.
//        m_camera.TriggerSelector.SetValue(TriggerSelector_AcquisitionStart);
        m_camera.TriggerSelector.SetValue(TriggerSelector_FrameStart);
        if(m_camera.TriggerSelector.GetValue() != TriggerSelector_FrameStart){
            printf(tr("Try Set FrameStart fail!\n").toLocal8Bit().data());
            return;
        }
        
        m_camera.RegisterConfiguration(m_configHandler, Pylon::RegistrationMode_Append, Pylon::Cleanup_Delete );
        
        if(m_isTriggerMonitor){
            m_camera.RegisterCameraEventHandler(m_eventHandler, "FrameStart", 10001, RegistrationMode_Append, Cleanup_None );
            if (m_camera.EventSelector.TrySetValue(EventSelector_FrameStart)){
                if (!m_camera.EventNotification.TrySetValue( EventNotification_On )){
                    m_camera.EventNotification.SetValue( EventNotification_GenICamEvent );
                }
            }
        }
        setStatus(Opened);
        return;
    } catch (const Pylon::GenericException& e) {
        PYLON_UNUSED( e );
        printf(e.GetDescription());
        qDebug() << tr("\n Open camera failed:") << QString::fromStdString(m_name);
    }
}
void CameraBasler::startGrabbing()
{
    if(m_status != Opened)
        return;
    if(!m_camera.IsOpen()){
        QString str = QString::fromStdString(m_name) + tr(" is not open, couldn't set grabbing");
        LOG(WARNING) << str.toLocal8Bit().data();
        return;
    }
    if(m_isNotRegisterImageCallBack){
            m_payLoadSize = m_camera.PayloadSize.GetValue();;
        }
        if(m_camera.IsGrabbing()){
            qDebug() << QString::fromStdString(m_name) << tr(" is grabbing, needn't start");
            return;
        } else {
            try {
                m_camera.AcquisitionMode.TrySetValue( Basler_UniversalCameraParams::AcquisitionMode_Continuous );
                m_camera.StartGrabbing(Pylon::GrabStrategy_OneByOne, Pylon::GrabLoop_ProvidedByInstantCamera );
            } catch (const Pylon::GenericException& e) {
                qDebug() << QString::fromStdString(m_name) << tr(" StartGrabbing failed!");
                printf(e.GetDescription());
                return;
            }
        }
        setStatus(Grabbing);
        emitMessage(tr("<font color=\'green\'>相机采集</font>"));

}
void CameraBasler::stopGrabbing()
{
    if(m_status != Grabbing)
        return;
    if(!m_camera.IsGrabbing()){
        qDebug() << QString::fromStdString(m_name) << tr(" is not grabbing, couldn't stop");
        return;
    } else {
        try {
            m_camera.StopGrabbing();
        } catch (const Pylon::GenericException& e) {
            qDebug() << QString::fromStdString(m_name) << tr(" StopGrabbing failed!");
            printf(e.GetDescription());
            return;
        }
    }
            emitMessage(tr("相机打开"));
        setStatus(Opened);
}
void CameraBasler::closeCamera()
{
    if(m_status != Opened)
    return;
    try {
        if(m_camera.IsOpen()){
            m_camera.Close();
        }

    } catch (const Pylon::GenericException& e) {
        PYLON_UNUSED( e );
        printf(e.GetDescription());
    }
            emitMessage(tr("相机关闭"));
        setStatus(Closed);
}
void CameraBasler::releaseCamera()
{
    if(m_camera.IsPylonDeviceAttached())
    {
        //注销回调
        m_camera.DeregisterConfiguration(m_configHandler);
        m_camera.DeregisterImageEventHandler(m_imageHandler);
        //销毁设备
        m_camera.DestroyDevice();
    }
    PylonTerminate();
    setStatus(Unavailable);
}
void CameraBasler::preProcessImage(const ImageInfo &imgInfo)
{
    if(imgInfo.pData == nullptr){
        return;
    }
    Pylon::EPixelType enDstPixelType = Pylon::EPixelType::PixelType_Undefined;
    unsigned int nChannelNum = 0;
    int cvFormat;

    if (Pylon::IsBGR((Pylon::EPixelType)imgInfo.enPixelType)){
        nChannelNum = 3;
        enDstPixelType = (Pylon::EPixelType)imgInfo.enPixelType==Pylon::EPixelType::PixelType_BGR8packed?Pylon::EPixelType::PixelType_Undefined:Pylon::EPixelType::PixelType_BGR8packed;
        //imgFormat = QImage::Format_RGB888;
        cvFormat = CV_8UC3;
    }
    else if (Pylon::IsMono((Pylon::EPixelType)imgInfo.enPixelType)){
        nChannelNum = 1;
        enDstPixelType = (Pylon::EPixelType)imgInfo.enPixelType==Pylon::EPixelType::PixelType_Mono8?Pylon::EPixelType::PixelType_Undefined:Pylon::EPixelType::PixelType_Mono8;
        //imgFormat = QImage::Format_Indexed8;
        cvFormat = CV_8UC1;
    }
    if (enDstPixelType == Pylon::EPixelType::PixelType_BGR8packed){
        cv::Mat cv_img(imgInfo.nHeight,imgInfo.nWidth,cvFormat,imgInfo.pData);
        emit sendCVImage(m_name, cv_img.clone());
    }else{
        cv::Mat cv_img(imgInfo.nHeight,imgInfo.nWidth,cvFormat,imgInfo.pData);
        emit sendCVImage(m_name, cv_img.clone());
    }
}
void CameraBasler::readCameraROI(const std::string& camName)
{
    if(m_status < Opened || camName != m_name)
        return;
    CameraROI cp;
    cp.width.nCurValue = m_camera.Width.GetValue();
    cp.height.nCurValue = m_camera.Height.GetValue();
    cp.off_x.nCurValue = m_camera.OffsetX.GetValue();
    cp.off_y.nCurValue = m_camera.OffsetY.GetValue();
    emit sigCameraROI(m_name,cp);
}
void CameraBasler::readCameraWhiteBalance(const std::string& camName)
{
    if(m_status < Opened || camName != m_name)
        return;
    CameraWhiteBalance cp;
    m_camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Red);
    cp.wb_r.nCurValue = m_camera.BalanceRatioAbs.GetValue();
    m_camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Green);
    cp.wb_g.nCurValue = m_camera.BalanceRatioAbs.GetValue();
    m_camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Blue);
    cp.wb_b.nCurValue = m_camera.BalanceRatioAbs.GetValue();
    emit sigCameraWhiteBalance(m_name,cp);
}
void CameraBasler::readCameraBrightness(const std::string& camName)
{
    if(m_status < Opened || camName != m_name)
        return;
    CameraBrightness cp;
    cp.exp.fCurValue = m_camera.ExposureTimeRaw.GetValue();
    cp.gain.fCurValue = m_camera.GainRaw.GetValue();
    emit sigCameraBrightness(m_name,cp);
}
void CameraBasler::readCameraTrigger(const std::string& camName)
{
    if(m_status < Opened || camName != m_name)
        return;
    TriggerType triggerType = TriggerOff;
    if(m_camera.TriggerMode.GetValue() == TriggerMode_Off){
        triggerType = TriggerOff;
    } else {
        if(m_camera.TriggerSource.GetValue() == TriggerSource_Line1){
            triggerType = TriggerLine0;
        } else if(m_camera.TriggerSource.GetValue() == TriggerSource_Software){
            triggerType = TriggerSoftware;
        }
    }
    CameraTrigger cp;
    cp.triggerMode = triggerType;
    cp.triggerDelay.fCurValue = m_camera.TriggerDelay.GetValue();
    emit sigCameraTrigger(m_name,cp);
}
void CameraBasler::readCameraTrans(const std::string& camName)
{
    if(m_status < Opened || camName != m_name)
        return;
    CameraTrans cp;
    cp.reverse_x = m_camera.ReverseX.GetValue();
    cp.reverse_y = m_camera.ReverseY.GetValue();
    emit sigCameraTrans(m_name,cp);
}

void CameraBasler::setCameraROI(const std::string& camName, const CameraROI &cp)
{
    if(camName != m_name)
        return;
    stopGrabbing();
    if(m_status != Opened)
        return;
    setWidth(m_name, cp.width);
    setHeight(m_name, cp.height);
    setOffsetX(m_name, cp.off_x);
    setOffsetY(m_name, cp.off_y);
    startGrabbing();
}
void CameraBasler::setCameraWhiteBalance(const std::string& camName, const CameraWhiteBalance &cp)
{
    if(camName != m_name)
        return;
    if(m_status < Opened)
        return;
    setWhiteBalanceR(m_name, cp.wb_r);
    setWhiteBalanceG(m_name, cp.wb_g);
    setWhiteBalanceB(m_name, cp.wb_b);
}
void CameraBasler::setCameraBrightness(const std::string& camName, const CameraBrightness &cp)
{
    if(camName != m_name)
        return;
    if(m_status < Opened)
        return;
    setExposureTime(m_name, cp.exp);
    setGain(m_name, cp.gain);
}
void CameraBasler::setCameraTrigger(const std::string& camName, const CameraTrigger &cp)
{
    if(camName != m_name)
        return;
    stopGrabbing();
    if(m_status != Opened)
        return;
    switch(cp.triggerMode){
    case TriggerOff:
        setTriggerModeOff();
        break;
    case TriggerLine0:
        setTriggerModeLine();
        break;
    case TriggerSoftware:
        setTriggerModeSoftware();
        break;
    }
    setTriggerDelay(camName,cp.triggerDelay);
    startGrabbing();
}
void CameraBasler::setCameraTrans(const std::string& camName, const CameraTrans &cp)
{
    if(camName != m_name)
        return;
    stopGrabbing();
    if(m_status != Opened)
        return;
    setReverseX(camName, cp.reverse_x);
    setReverseY(camName, cp.reverse_y);
    startGrabbing();
}

void CameraBasler::triggerSoftware()
{
    //软触发采集
    if(m_status != Grabbing)
        return;
    try {
        TriggerModeEnums oldstr;
        TriggerSourceEnums oldSource;
        oldstr = m_camera.TriggerMode.GetValue();
        oldSource = m_camera.TriggerSource.GetValue();
        if(oldstr != TriggerMode_On && oldSource != TriggerSource_Software){
            qDebug() << QString::fromStdString(m_name) << tr(" softWare not set, can not trigger");
            return;
        }
        qDebug() << tr("softWare trigger");
        m_camera.TriggerSoftware.Execute();
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" triggerSoftware failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setExposureTime(const std::string &camName, const FloatValue &value)
{
    if(!m_camera.IsPylonDeviceAttached() || camName != m_name)
        return;
    try {
        m_camera.ExposureAuto.SetValue(ExposureAuto_Off);
        int64_t min = m_camera.ExposureTimeAbs.GetMin();
        int64_t max = m_camera.ExposureTimeAbs.GetMax();
        int64_t value_set = int64_t(value.fCurValue < min ? min : value.fCurValue);
        value_set = int64_t(value.fCurValue > max ? max : value.fCurValue);
        m_camera.ExposureTimeAbs.SetValue(value_set);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setExposureTime failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setExposureAutoMode(const std::string &camName, const IntValue &expMode)
{
    if(!m_camera.IsPylonDeviceAttached() || camName != m_name)
        return;
    try {
        m_camera.ExposureAuto.SetValue(ExposureAutoEnums(expMode.nCurValue));
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setExposureAutoMode failed!");
        printf(e.GetDescription());
        return;
    }
}
void CameraBasler::setWidth(const std::string &camName, const IntValue &value)
{
    if(m_status != Opened || camName != m_name)
        return;
    try {
        int64_t min = m_camera.Width.GetMax();
        int64_t max = m_camera.Width.GetMax();
        int64_t value_set = int64_t(value.nCurValue < min ? min : value.nCurValue);
        value_set = int64_t(value.nCurValue > max ? max : value.nCurValue);
        m_camera.Width.SetValue(value_set);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setWidth failed!");
        printf(e.GetDescription());
        return;
    }
}
void CameraBasler::setHeight(const std::string &camName, const IntValue &value)
{
    if(m_status != Opened || camName != m_name)
        return;
    try {
        int64_t min = m_camera.Height.GetMin();
        int64_t max = m_camera.Height.GetMax();
        int64_t value_set = int64_t(value.nCurValue < min ? min : value.nCurValue);
        value_set = int64_t(value.nCurValue > max ? max : value.nCurValue);
        m_camera.Height.SetValue(value_set);

    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setHeight failed!");
        printf(e.GetDescription());
        return;
    }
}
void CameraBasler::setOffsetX(const std::string &camName, const IntValue &value)
{
    if(m_status != Opened || camName != m_name)
        return;
    try {
        int64_t min = m_camera.OffsetX.GetMin();
        int64_t max = m_camera.OffsetX.GetMax();
        int64_t value_set = int64_t(value.nCurValue < min ? min : value.nCurValue);
        value_set = int64_t(value.nCurValue > max ? max : value.nCurValue);
        m_camera.OffsetX.SetValue(value_set);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setOffsetX failed!");
        printf(e.GetDescription());
        return;
    }
}
void CameraBasler::setOffsetY(const std::string &camName, const IntValue &value)
{
    if(m_status != Opened || camName != m_name)
        return;
    try {
        int64_t min = m_camera.OffsetY.GetMin();
        int64_t max = m_camera.OffsetY.GetMax();
        int64_t value_set = int64_t(value.nCurValue < min ? min : value.nCurValue);
        value_set = int64_t(value.nCurValue > max ? max : value.nCurValue);
        m_camera.OffsetY.SetValue(value_set);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setOffsetY failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setReverseX(const std::string &camName, const bool &reverse_x)
{
    if(m_status != Opened || camName != m_name)
        return;
    try {
        m_camera.ReverseX.SetValue(reverse_x);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setReverseX failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setReverseY(const std::string &camName, const bool &reverse_y)
{
    if(m_status != Opened || camName != m_name)
        return;
    try {
        m_camera.ReverseY.SetValue(reverse_y);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setReverseY failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setWhiteBalanceR(const std::string &camName, const IntValue &wb_r)
{
    if(!m_camera.IsPylonDeviceAttached() || camName != m_name)
        return;
    try {
        m_camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Red);
        m_camera.BalanceRatioAbs.SetValue(wb_r.nCurValue);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setWhiteBalanceR failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setWhiteBalanceG(const std::string &camName, const IntValue &wb_g)
{
    if(!m_camera.IsPylonDeviceAttached() || camName != m_name)
        return;
    try {
        m_camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Green);
        m_camera.BalanceRatioAbs.SetValue(wb_g.nCurValue);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setWhiteBalanceG failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setWhiteBalanceB(const std::string &camName, const IntValue &wb_b)
{
    if(!m_camera.IsPylonDeviceAttached() || camName != m_name)
        return;
    try {
        m_camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Blue);
        m_camera.BalanceRatioAbs.SetValue(wb_b.nCurValue);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setWhiteBalanceB failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setGain(const std::string &camName, const FloatValue &value)
{
    if(m_status!=Opened || camName!=m_name)
        return;
    try {
        m_camera.GainAuto.SetValue(GainAuto_Off);
        m_camera.GainSelector.SetValue(GainSelector_All);
        int64_t min = m_camera.GainRaw.GetMin();
        int64_t max = m_camera.GainRaw.GetMax();
        int64_t value_set = int64_t(value.fCurValue < min ? min : value.fCurValue);
        value_set = int64_t(value.fCurValue > max ? max : value.fCurValue);
        m_camera.GainRaw.SetValue(value_set);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setGain failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::getOneFrame()
{
    if(!m_camera.IsGrabbing()){
        qDebug() << QString::fromStdString(m_name) << tr("camera is not grabbing now!");
        return;
    }
    CGrabResultPtr ptrGrabResult;
    m_camera.GrabOne(2000, ptrGrabResult);
    if (ptrGrabResult.IsValid() && ptrGrabResult->GrabSucceeded())
    {
        ImageInfo imgInfo={0};
        if ( ptrGrabResult->GetPixelType() == Pylon::PixelType_Mono8)
        {

        } else {
            Pylon::CPylonImage tarImage;
            // Create the converter and set parameters.
            Pylon::CImageFormatConverter converter;
            converter.OutputPixelFormat = Pylon::PixelType_BGR8packed;
            converter.Convert(tarImage, ptrGrabResult);
            imgInfo.pData = (uchar*)ptrGrabResult->GetBuffer();
        }
        imgInfo.nWidth = ptrGrabResult->GetWidth();
        imgInfo.nHeight = ptrGrabResult->GetHeight();
        imgInfo.pData = (uchar*)ptrGrabResult->GetBuffer();
        imgInfo.nDataLen = Pylon::ComputeBufferSize(ptrGrabResult->GetPixelType(), ptrGrabResult->GetWidth(),
                                                    ptrGrabResult->GetHeight(), ptrGrabResult->GetPaddingX());
        imgInfo.enPixelType = ptrGrabResult->GetPixelType();
        emit preProcessImage(imgInfo);
    }
}

//void CameraBasler::setFrameRate(int rate)
//{
//    if(!m_camera.IsOpen()){
//        QString str = QString::fromStdString(m_name) + tr(" is not open, couldn't set FrameRate");
//        LOG(WARNING) << str.toLocal8Bit().data();
//        qDebug() << str;
//    }
//    try {
//        m_camera.AcquisitionFrameRateEnable.SetValue(true);
//        m_camera.AcquisitionFrameRateAbs.SetValue(rate);
//    } catch (const Pylon::GenericException& e) {
//        qDebug() << QString::fromStdString(m_name) << tr(" setFrameRate failed!");
//        printf(e.GetDescription());
//        return;
//    }
//}



void CameraBasler::setTriggerModeOff()
{ 
    if (!m_camera.IsOpen())
        return;
    if(m_camera.IsGrabbing()){
        qDebug() << QString::fromStdString(m_name) << tr("camera is grabbing now!");
        return;
    }
    try {
        m_camera.TriggerMode.SetValue(TriggerMode_Off);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setTriggerMode Off failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setTriggerModeOn()
{
    if (!m_camera.IsOpen())
        return;
    if(m_camera.IsGrabbing()){
        qDebug() << QString::fromStdString(m_name) << tr("camera is grabbing now!");
        return;
    }
    try {
        m_camera.TriggerMode.SetValue(TriggerMode_On);
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setTriggerMode On failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setTriggerModeSoftware()
{
    if (!m_camera.IsOpen())
        return;
    if(m_camera.IsGrabbing()){
        qDebug() << QString::fromStdString(m_name) << tr("camera is grabbing now!");
        return;
    }
    try {
        m_camera.TriggerMode.SetValue(TriggerMode_On);
        TriggerModeEnums nRet = m_camera.TriggerMode.GetValue();
        if (nRet != TriggerMode_On)    {
            LOG(WARNING)<< tr("set TriggerMode On failed!").toLocal8Bit().data();
            return;
        }
        m_camera.TriggerSource.SetValue(TriggerSource_Software);
        TriggerSourceEnums nRet1 = m_camera.TriggerSource.GetValue();
        if (nRet1 != TriggerSource_Software)    {
            LOG(WARNING)<< tr("set TriggerSource Software failed!").toLocal8Bit().data();
            return;
        }
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setTriggerMode Software failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setTriggerModeLine()
{
    if (!m_camera.IsOpen())
        return;
    if(m_camera.IsGrabbing()){
        qDebug() << tr("camera is grabbing now!");
        return;
    }

    try {
        m_camera.TriggerMode.SetValue(TriggerMode_On);
        TriggerModeEnums nRet = m_camera.TriggerMode.GetValue();
        if (nRet != TriggerMode_On)    {
            LOG(WARNING)<< tr("set TriggerMode On failed!").toLocal8Bit().data();
            return;
        }
        m_camera.TriggerSource.SetValue(TriggerSource_Line1);
        TriggerSourceEnums nRet1 = m_camera.TriggerSource.GetValue();
        if (nRet1 != TriggerSource_Line1)    {
            LOG(WARNING)<< tr("set TriggerSource Line1 failed!").toLocal8Bit().data();
            return;
        }
    } catch (const Pylon::GenericException& e) {
        qDebug() << QString::fromStdString(m_name) << tr(" setTriggerMode Line failed!");
        printf(e.GetDescription());
        return;
    }
}

void CameraBasler::setTriggerDelay(const std::string &camName, const FloatValue &delay)
{

}


